package com.qifan.alb2b.service;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.stereotype.Service;
import com.qifan.alb2b.exception.BusinessException;
import com.qifan.alb2b.action.back.param.RouteQueryParam;
import com.qifan.alb2b.dao.CityInfoDao;
import com.qifan.alb2b.dao.HotelInfoDao;
import com.qifan.alb2b.dao.RouteDetailInfoDao;
import com.qifan.alb2b.dao.RouteInfoDao;
import com.qifan.alb2b.domain.CarInfoDomain;
import com.qifan.alb2b.domain.CityInfoDomain;
import com.qifan.alb2b.domain.GuideInfoDomain;
import com.qifan.alb2b.domain.HotelInfoDomain;
import com.qifan.alb2b.domain.RouteDetailInfoDomain;
import com.qifan.alb2b.domain.RouteInfoDomain;
import com.qifan.alb2b.service.resource.IResource;
import com.qifan.alb2b.service.resource.ResourceFactory;
import com.qifan.alb2b.service.route.StPriceContext;
import com.qifan.alb2b.service.vo.ResourceVo;
import com.qifan.alb2b.service.vo.RouteDetailVo;
import com.qifan.alb2b.service.vo.RouteVo;
import com.qifan.alb2b.service.vo.StPriceTable;
import com.qifan.alb2b.util.Constants;
import com.qifan.alb2b.util.DataGridModel;
import com.qifan.alb2b.util.ExchangeUtil;
import com.qifan.alb2b.util.ID;
import com.qifan.alb2b.util.Objecter;
import com.qifan.alb2b.util.Page;

/**
 * 线路业务类
 * @author hc24
 *
 */
@Service
public class RouteInfoService {
	private static final Log logger=LogFactory.getLog(RouteInfoService.class);
	
	private RouteInfoDao routeInfoDao;
	private RouteDetailInfoDao routeDetailInfoDao;
	private CityInfoDao cityInfoDao;
	private StPriceContext stPriceContext;
	private ResourceFactory resourceFactory;


	public void setRouteInfoDao(RouteInfoDao routeInfoDao) {
		this.routeInfoDao = routeInfoDao;
	}
	
	public void setRouteDetailInfoDao(RouteDetailInfoDao routeDetailInfoDao) {
		this.routeDetailInfoDao = routeDetailInfoDao;
	}
	
	public void setCityInfoDao(CityInfoDao cityInfoDao) {
		this.cityInfoDao = cityInfoDao;
	}


	public void setStPriceContext(StPriceContext stPriceContext) {
		this.stPriceContext = stPriceContext;
	}
	
	public void setResourceFactory(ResourceFactory resourceFactory) {
		this.resourceFactory = resourceFactory;
	}

	public Page query(DataGridModel dgm,RouteQueryParam rqp){
		return routeInfoDao.query(dgm, rqp);
	}
	
	public RouteInfoDomain queryRouteById(String routeId){
		RouteInfoDomain route=routeInfoDao.getRouteById(routeId);
		if(route==null)
			throw new BusinessException("您操作的线路不存在,可能已经删除，请刷新后重拾");
		return route;
	}
	
	/**
	 * 根据线路id查询该线路的详情
	 * @param routeId 线路id
	 * @return
	 */
	public Page queryDetial(String routeId){
		return routeDetailInfoDao.query(routeId);
	}
	
	public RouteDetailInfoDomain queryDetailById(String detailId){
		RouteDetailInfoDomain rdid= routeDetailInfoDao.getDetailById(detailId);
		if(rdid==null)
			throw new BusinessException("id为"+detailId+"的线路详情不存在,可能已经删除，请刷新后重试");
		return rdid;
	}
	
	/**
	 * 添加新的线路并生成默认的线路详情信息
	 * @param routeInfoDomain
	 */
	public void add(RouteInfoDomain routeInfoDomain){
		routeInfoDomain.setStatus(Constants.ROUTE_STATUS_INVALID);//设置线路无效
		routeInfoDao.add(routeInfoDomain);//增加线路详情
		String what="待定";
		
		//设置第一天
		RouteDetailInfoDomain rdid=new RouteDetailInfoDomain();
		rdid.setDetailId(ID.next()+"");
		rdid.setRouteId(routeInfoDomain.getRouteId());//设置线路id
		rdid.setWhichDay(1);//第一天
		rdid.setDepart(what);//出发
		rdid.setArrivel(routeInfoDomain.getOrgCityCn());//设置第一天的到达地
		rdid.setCityId("");
		rdid.setCityCn("");
		rdid.setRemark("");
		routeDetailInfoDao.add(rdid);
		
		//循环添加当中的天数
		for(int n=2;n<routeInfoDomain.getDay();n++){
			rdid=new RouteDetailInfoDomain();
			rdid.setDetailId(ID.next()+"");
			rdid.setRouteId(routeInfoDomain.getRouteId());//设置线路id
			rdid.setWhichDay(n);//第n天
			rdid.setDepart(what);//出发
			rdid.setArrivel(what);//设置第一天的到达地
			rdid.setCityId("");
			rdid.setCityCn("");
			rdid.setRemark("");
			routeDetailInfoDao.add(rdid);
		}
		
		//添加最后一天
		rdid=new RouteDetailInfoDomain();
		rdid.setDetailId(ID.next()+"");
		rdid.setRouteId(routeInfoDomain.getRouteId());//设置线路id
		rdid.setWhichDay(routeInfoDomain.getDay());//最后一天
		rdid.setDepart(routeInfoDomain.getDstCityCn());//最后一天到达地
		rdid.setArrivel(what);//设置第一天的到达地
		rdid.setCityId("");
		rdid.setCityCn("");
		rdid.setRemark("");
		routeDetailInfoDao.add(rdid);
	}
	
	public void update(RouteInfoDomain routeInfoDomain){
		routeInfoDao.update(routeInfoDomain);
	}
	
	/**
	 * 更新线路的状态，同时计算线路的最低价格
	 * @param routeId 
	 * @param status 0：开通   1：关闭  2：线路无效
	 */
	public void updateStatus(String routeId,int status){
		RouteInfoDomain route=routeInfoDao.getRouteById(routeId);
		if(status==Constants.ROUTE_STATUS_OPEN){//开通线路要验证是否具备开通的条件
			//验证该线路详情是否每天都设置了目的地信息（用于计算价格）
			List<RouteDetailInfoDomain> list=routeDetailInfoDao.query(routeId).getRows();
			for(RouteDetailInfoDomain detail:list){
				if(detail.getCityId()==null||"".equals(detail.getCityId().trim())){
					throw new BusinessException("本线路行程中中第"+detail.getWhichDay()+
							"天还未设置目的地，请在编辑线路详情中设置后再开通");
				}
			}
		}
		route.setStatus(status);
		
		//计算最低价格
		route.setLowestPrice1((float) stPriceContext.getLowest(route,Constants.GROUP_TYPE_SIX));//1-6人团的最低价格
		route.setLowestPrice2((float) stPriceContext.getLowest(route,Constants.GROUP_TYPE_SEVEN));//7-38人团的最低价格
		
		routeInfoDao.update(route);	
	}
	
	/**
	 * 更新线路详情
	 * @param detailList
	 */
	public void updateDetail(RouteDetailInfoDomain rdid){		
		routeDetailInfoDao.update(rdid);		
	}
	
	/**
	 * 删除线路
	 * 1、对于已有订单的线路不允许删除<br/>
	 * 2、同时删除关联的线路详情信息
	 * @param routeId
	 */
	public void deleteRoute(String routeId){
		//判断是否有关联的订单
		if(routeInfoDao.getOrderCountByRoute(routeId)>0)
			throw new BusinessException("该线路存在关联的订单,不能删除!");
		routeDetailInfoDao.delete(routeId);//删除关联的线路详情
		routeInfoDao.delete(new String[]{routeId});//删除线路
	}
	
	//===============================前台=================================
	/**
	 * 根据线路ID和团体类型获得线路的标准配套价格
	 */
	public RouteVo queryRouteVo(String routeId,int groupType){
		RouteInfoDomain route=routeInfoDao.getRouteById(routeId);
		List<RouteDetailInfoDomain> detailList=routeDetailInfoDao.query(routeId).getRows();
		StPriceTable spt = stPriceContext.getStPriceTable(route, groupType);
		RouteVo routeVo=new RouteVo();
		routeVo.setRoute(route);
		routeVo.setStPriceTable(spt);
		try {
			routeVo.setInitStPriceTable((StPriceTable) Objecter.decode(Objecter.encode(spt)));
		} catch (Exception e) {
			e.printStackTrace();
		}
		routeVo.setGroupType(groupType);
		
		//设置线路详情
		List<RouteDetailVo> detailVoList=new ArrayList<RouteDetailVo>();
		for(int i=0;i<detailList.size();i++){
			RouteDetailVo rdVo=new RouteDetailVo();
			rdVo.setRouteDetail(detailList.get(i));			
			detailVoList.add(rdVo);
		}
		routeVo.setDetailVoList(detailVoList);
		//设置线路详情中所包含的资源,初始化是标配的资源
		stPriceContext.initStRes(routeVo, groupType);		
		
		return routeVo;
	}
	
	/**
	 * 添加晚宿
	 * @param routeVo
	 * @param routeDetailId 
	 */
	public void addNight(RouteVo routeVo,String routeDetailId){
		try {
			//查找线路详情
			RouteInfoDomain route=routeVo.getRoute();
			List<RouteDetailVo> detailList= routeVo.getDetailVoList();
			int i=0;
			RouteDetailVo routeDetail = null;
			for(;i<detailList.size();i++){
				RouteDetailVo rdv=detailList.get(i);
				if(routeDetailId.equals(rdv.getRouteDetail().getDetailId())){//找到当前线路详情
					routeDetail=rdv;
					break;//找到了当前线路详情则结束循环
				}//end if
			}//end for
			if(routeDetail==null)
				throw new BusinessException("添加留宿的当天线路详情不存在，请刷新后重试");
			
			boolean isLast=false;
			if(i+1>route.getNight())
				isLast=true;
			RouteDetailVo newRdv=null;//新的一天
		
			newRdv=(RouteDetailVo) Objecter.decode(Objecter.encode(routeDetail));
			//①设置新的线路详情id，并用nw做前缀代表是新添加的。
			newRdv.getRouteDetail().setDetailId("NW"+ID.next());
			//②更新天数
			newRdv.getRouteDetail().setWhichDay(i+2);//后一天
			for(int n=i;n<detailList.size();n++){//之后的天数也要变化
				detailList.get(n).getRouteDetail().setWhichDay(n+2);
			}
			route.setDay(route.getDay()+1);//线路中增加天数
			route.setNight(route.getNight()+1);//线路中增加夜晚数
			//③更新资源，新添加的只设置标配资源
			HotelInfoDomain hotel=null;
			CarInfoDomain car=null;
			GuideInfoDomain guide=null;
			List<ResourceVo> resList=newRdv.getResList();
			for(int n=0;n<resList.size();n++){
				if(resList.get(n).getResType()==Constants.RES_TYPE_HOTEL){
					hotel=(HotelInfoDomain) resList.get(n).getResource();
				}
				if(resList.get(n).getResType()==Constants.RES_TYPE_CAR){
					car=(CarInfoDomain) resList.get(n).getResource();
				}
				if(resList.get(n).getResType()==Constants.RES_TYPE_GUIDE){
					guide=(GuideInfoDomain) resList.get(n).getResource();
				}	
			}
			newRdv.setResList(new ArrayList<ResourceVo>());//设置一个空的的列表
			routeVo.getDetailVoList().add(i+1, newRdv);//插入
			if(hotel!=null){
				IResource hotelRes=resourceFactory.newResouce(Constants.RES_TYPE_HOTEL);
				hotelRes.addOrUpdate(routeVo, newRdv.getRouteDetail().getDetailId(), new String[]{hotel.getHotelId()});//增加酒店标配
			}
			if(car!=null){
				IResource carRes=resourceFactory.newResouce(Constants.RES_TYPE_CAR);
				carRes.addOrUpdate(routeVo, newRdv.getRouteDetail().getDetailId(), new String[]{car.getCarId()});//增加接送标配
			}
			if(guide!=null){
				IResource guideRes=resourceFactory.newResouce(Constants.RES_TYPE_GUIDE);
				guideRes.addOrUpdate(routeVo, newRdv.getRouteDetail().getDetailId(), new String[]{guide.getGuideId()});//增加导游标配
			}
			
			//④判断是否是n天n-1夜的情况，需要对n天添加标配住宿资源
			if(isLast){
				CityInfoDomain city=cityInfoDao.getCityById(routeDetail.getRouteDetail().getCityId());
				IResource resource=resourceFactory.newResouce(Constants.RES_TYPE_HOTEL);
				resource.addOrUpdate(routeVo, routeDetailId, new String[]{city.getHotelId()});//更新标配价格
			}
			
			
		} catch (Exception e) {	
			logger.equals(e);
			throw new BusinessException("添加留宿失败！请重现选择线路预定");//一旦失败就失败，不可能改
		}
		
	}
	
	/**
	 * 删除晚宿
	 * @param routeVo
	 * @param routeDetailId
	 */
	public void delNight(RouteVo routeVo, String routeDetailId) {
		try{
			//查找要删除的线路详情
			RouteInfoDomain route=routeVo.getRoute();
			List<RouteDetailVo> detailList= routeVo.getDetailVoList();
			int i=0;
			RouteDetailVo routeDetail = null;
			for(;i<detailList.size();i++){
				RouteDetailVo rdv=detailList.get(i);
				if(routeDetailId.equals(rdv.getRouteDetail().getDetailId())
						&&rdv.getRouteDetail().getDetailId().startsWith("NW")){//找到当前线路详情
					routeDetail=rdv;
					break;//找到了当前线路详情则结束循环
				}//end if
			}//end for
			if(routeDetail==null)
				throw new BusinessException("删除留宿的当天线路详情不存在，请刷新后重试");
			
			boolean isLast=false;
			if(i+1>route.getNight())
				isLast=true;
			
			
			//①删除要删除线路的资源列表，然后删除线路详情本身
			List<ResourceVo> resList=routeDetail.getResList();
			for(int n=0;n<resList.size();n++){
				IResource resource=resourceFactory.newResouce(resList.get(n).getResType());
				resource.addOrUpdate(routeVo, routeDetailId, new String[]{});//空列表代表删除
				n=-1;
			}
			detailList.remove(i);
			
			//②更新天数
			for(int n=i;n<detailList.size();n++){
				detailList.get(n).getRouteDetail().setWhichDay(n);
			}
			route.setDay(route.getDay()-1);
			route.setNight(route.getNight()-1);
			
			//③判断是否是最后一天有无晚宿的情况，把最后一天的酒店给清除了
			if(isLast){
				RouteDetailVo lastRdv=detailList.get(detailList.size()-1);
				IResource resource=resourceFactory.newResouce(Constants.RES_TYPE_HOTEL);
				resource.addOrUpdate(routeVo, lastRdv.getRouteDetail().getDetailId(), new String[]{});//删除酒店
			}
			
		}catch(Exception e){
			
		}
		
	}
		
}
